from rest_framework.views import exception_handler
from rest_framework.response import Response
from rest_framework import status
from django.db import DatabaseError
from redis.exceptions import RedisError
from rest_framework.exceptions import Throttled
from base_utils.logger import logger
from base_utils.response_fmt import get_response_dict
from base_utils.exception import BaseError
from base_utils.response_http_code import (
    BadRequestStatus,
    SuccessStatus,
    ServerErrorStatus,
)


# 全局异常处理类
def custom_exception_handler(exc, context):
    """
    自定义全局异常处理
    """
    # 1. 先调用DRF默认的异常处理
    response = exception_handler(exc, context)
    # 对已知的限速类处理
    if isinstance(exc, Throttled):
        wait_time = exc.wait
        response.status_code = SuccessStatus.http_code
        response.data = get_response_dict(
            BadRequestStatus.http_code, f"请求过于频繁,在{wait_time}秒后再次请求"
        )
    elif response is not None:
        # 2. 对DRF已知异常格式化输出
        # 错误的状态码=response.status_code
        status_code = response.status_code
        code = (
            BadRequestStatus.http_code
            if status_code != ServerErrorStatus.http_code
            else ServerErrorStatus.http_code
        )
        # 自定义的请求码
        response.data = get_response_dict(
            code,
            response.data.get("detail") if "detail" in response.data else response.data,
        )
        # http的响应码
        response.status_code = (
            SuccessStatus.http_code
            if status_code != ServerErrorStatus.http_code
            else ServerErrorStatus.http_code
        )
    else:
        # 3. 处理DRF未捕获的异常
        if isinstance(exc, DatabaseError) or isinstance(exc, RedisError):
            # 数据库/缓存异常
            logger.exception(f"[服务器错误] {exc}")
            data = get_response_dict(
                status.HTTP_500_INTERNAL_SERVER_ERROR, "系统内部错误"
            )
            response = Response(data, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        elif isinstance(exc, BaseError):
            # 对于自定义的异常，交给中间件处理,exception_middle处理
            pass
        else:
            # 其他未知异常
            logger.exception(f"[未知错误] {exc}")
            data = get_response_dict(
                status.HTTP_500_INTERNAL_SERVER_ERROR, f"接口异常,{str(exc)}"
            )
            response = Response(data, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    return response
